package com.wuxu.lib_skin_core.utils

import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.res.AssetManager
import android.content.res.Resources
import android.os.Build

/**
 *@author wuxu
 *@date 2024/5/22 10:01
 *@description
 */
object SkinApkUtils {
    private val skinApkInfoCache by lazy { HashMap<String, SkinApkInfo>() }

    fun getSkinApkInfo(context: Context, skinPath:String):SkinApkInfo? {
        if (skinApkInfoCache.containsKey(skinPath)){
            return skinApkInfoCache[skinPath]
        }



        var resource:Resources?=null

        val skinPackageInfo: PackageInfo? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            context.packageManager.getPackageArchiveInfo(skinPath, PackageManager.PackageInfoFlags.of(0))
        }else{
            context.packageManager.getPackageArchiveInfo(skinPath,0)
        }

        if(skinPackageInfo==null){
            return null
        }

        skinPackageInfo.applicationInfo?.sourceDir = skinPath
        skinPackageInfo.applicationInfo?.publicSourceDir=skinPath

        val skinApkPackageName:String = skinPackageInfo.packageName


        try {
            //直接获取某个已安装apk的resource信息
            resource = context.packageManager.getResourcesForApplication(skinPackageInfo.applicationInfo)
        }catch (e: PackageManager.NameNotFoundException){
            e.printStackTrace()
        }


        if (resource==null){
            //反射获取非安装应用的resources文件
            val assetManager = AssetManager::class.java.newInstance()
            val addAssetPathMethod= assetManager.javaClass.getDeclaredMethod("addAssetPath",assetManager.javaClass)
            addAssetPathMethod.isAccessible = true
            addAssetPathMethod.invoke(assetManager,skinPath)

            resource = Resources(assetManager,context.resources.displayMetrics,context.resources.configuration)
        }

        return SkinApkInfo(resource,skinApkPackageName,skinPackageInfo)
    }

}

data class SkinApkInfo(
    val resources: Resources?=null,
    val packageName:String?=null,
    val packageArchiveInfo:PackageInfo?=null
){
    override fun toString(): String {
        return "SkinApkInfo(resources=$resources, packageName=$packageName, packageArchiveInfo=$packageArchiveInfo)"
    }
}
